#include "gpio.h"

/********** Button **********/
/********** Button **********/
/********** Button **********/
/**
 * @brief  GPIO初始化(Button)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_Button_Init(void)
{
#ifdef BUTTON_UP_GPIO_CLK_ENABLE
    BUTTON_UP_GPIO_CLK_ENABLE();
    gpio_init(BUTTON_UP_GPIO_Port,
              GPIO_MODE_IPU,
              GPIO_OSPEED_50MHZ,
              BUTTON_UP_Pin);
#endif

#ifdef BUTTON_DOWN_GPIO_CLK_ENABLE
    /* GPIO Ports Clock Enable*/
    BUTTON_DOWN_GPIO_CLK_ENABLE(); // 启用DOWN端口时钟
    /*Configure GPIO pin*/
    gpio_init(BUTTON_DOWN_GPIO_Port,
              GPIO_MODE_IPU,
              GPIO_OSPEED_50MHZ,
              BUTTON_DOWN_Pin);
#endif
}

/********** HwElec **********/
/********** HwElec **********/
/********** HwElec **********/
/**
 * @brief  GPIO初始化(HwElec)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_HwElec_Init(void)
{
    /* GPIO Ports Clock Enable*/
    HW_ELEC_AP_GPIO_CLK_ENABLE(); // 启用AP端口时钟
    HW_ELEC_AM_GPIO_CLK_ENABLE(); // 启用AM端口时钟
    HW_ELEC_BP_GPIO_CLK_ENABLE(); // 启用BP端口时钟
    HW_ELEC_BM_GPIO_CLK_ENABLE(); // 启用BM端口时钟
    /*Configure GPIO pins*/
    gpio_init(HW_ELEC_AP_GPIO_Port,
              GPIO_MODE_OUT_PP,
              GPIO_OSPEED_50MHZ,
              HW_ELEC_AP_Pin);
    /*Configure GPIO pins*/
    gpio_init(HW_ELEC_AM_GPIO_Port,
              GPIO_MODE_OUT_PP,
              GPIO_OSPEED_50MHZ,
              HW_ELEC_AM_Pin);
    /*Configure GPIO pins*/
    gpio_init(HW_ELEC_BP_GPIO_Port,
              GPIO_MODE_OUT_PP,
              GPIO_OSPEED_50MHZ,
              HW_ELEC_BP_Pin);
    /*Configure GPIO pins*/
    gpio_init(HW_ELEC_BM_GPIO_Port,
              GPIO_MODE_OUT_PP,
              GPIO_OSPEED_50MHZ,
              HW_ELEC_BM_Pin);
    /*Configure GPIO pin Output Level*/
    gpio_bit_reset(HW_ELEC_AP_GPIO_Port, HW_ELEC_AP_Pin); // AP引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_AM_GPIO_Port, HW_ELEC_AM_Pin); // AM引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_BP_GPIO_Port, HW_ELEC_BP_Pin); // BP引脚启动输出低电平
    gpio_bit_reset(HW_ELEC_BM_GPIO_Port, HW_ELEC_BM_Pin); // BM引脚启动输出低电平
}

/********** OLED **********/
/********** OLED **********/
/********** OLED **********/
/**
 * @brief  GPIO初始化(OLED)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_OLED_Init(void)
{
#ifdef OLED_SPI_CS_GPIO_CLK_ENABLE
    /********** CS **********/
    /*GPIO Ports Clock Enable*/
    OLED_SPI_CS_GPIO_CLK_ENABLE(); // 启用CS端口时钟
    /*Configure GPIO pin Output Level*/
    gpio_bit_reset(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin); // CS启动输出低电平

    /*Configure GPIO pins*/
    gpio_init(OLED_SPI_CS_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, OLED_SPI_CS_Pin);
#endif

    /********** RES **********/
    /*GPIO Ports Clock Enable*/
    OLED_SPI_RES_GPIO_CLK_ENABLE(); // 启用RES端口时钟
    /*Configure GPIO pin Output Level*/
    gpio_bit_reset(OLED_SPI_RES_GPIO_Port, OLED_SPI_RES_Pin); // RES启动输出低电平
    /*Configure GPIO pins*/
    gpio_init(OLED_SPI_RES_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, OLED_SPI_RES_Pin);

    /********** DC **********/
    /*GPIO Ports Clock Enable*/
    OLED_SPI_DC_GPIO_CLK_ENABLE(); // 启用DC端口时钟
    /*Configure GPIO pin Output Level*/
    gpio_bit_reset(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin); // DC启动输出低电平
    /*Configure GPIO pins*/
    gpio_init(OLED_SPI_DC_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, OLED_SPI_DC_Pin);
}

/********** SIGNAL **********/
/********** SIGNAL **********/
/********** SIGNAL **********/
/**
 * @brief  GPIO初始化(SIGNAL_COUNT)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_SIGNAL_COUNT_Init(void)
{
#ifdef SIGNAL_COUNT_ENA_CLK_ENABLE
    /*GPIO Ports Clock Enable*/
    SIGNAL_COUNT_ENA_CLK_ENABLE(); // 启用ENA端口时钟
    /*Configure GPIO pins*/
    gpio_init(SIGNAL_COUNT_ENA_GPIO_Port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SIGNAL_COUNT_ENA_Pin);
#endif

#ifdef SIGNAL_COUNT_DIR_CLK_ENABLE
    /*GPIO Ports Clock Enable*/
    rcu_periph_clock_enable(RCU_GPIOA); // 启用DIR端口时钟
    /*Configure GPIO pins*/
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
    nvic_irq_enable(EXTI5_9_IRQn, 0U, 0U);
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_7);
    exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
    exti_interrupt_flag_clear(EXTI_7);
#endif
}

/**
 * @brief  GPIO清理(SIGNAL_COUNT)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_SIGNAL_COUNT_DeInit(void)
{
    /*EXTI interrupt deinit*/
    nvic_irq_disable(SIGNAL_COUNT_DIR_Get_IRQn);
    // 重置DIR引脚配置
    gpio_init(SIGNAL_COUNT_DIR_GPIO_Port,
              GPIO_MODE_AIN,    // 模拟输入模式（最低功耗）
              GPIO_OSPEED_2MHZ, // 低速配置
              SIGNAL_COUNT_DIR_Pin);

    // 重置ENA引脚配置
    gpio_init(SIGNAL_COUNT_ENA_GPIO_Port,
              GPIO_MODE_AIN,
              GPIO_OSPEED_2MHZ,
              SIGNAL_COUNT_ENA_Pin);
}

/**
 * @brief  GPIO初始化(SIGNAL_PWM)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_SIGNAL_PWM_Init(void)
{
    /*GPIO Ports Clock Enable*/
    SIGNAL_PWM_ENA_CLK_ENABLE(); // 启用ENA端口时钟
    SIGNAL_PWM_DIR_CLK_ENABLE(); // 启用DIR端口时钟
    /*Configure GPIO pins*/
    gpio_init(SIGNAL_PWM_ENA_GPIO_Port,
              GPIO_MODE_IN_FLOATING,
              GPIO_OSPEED_MAX,
              SIGNAL_PWM_ENA_Pin);

    /*Configure GPIO pins*/
    gpio_init(SIGNAL_PWM_DIR_GPIO_Port,
              GPIO_MODE_IPU,
              GPIO_OSPEED_MAX,
              SIGNAL_PWM_DIR_Pin);
}

/**
 * @brief  GPIO清理(SIGNAL_PWM)
 * @param  NULL
 * @retval NULL
 */
void REIN_GPIO_SIGNAL_PWM_DeInit(void)
{
    // 重置DIR引脚配置
    gpio_init(SIGNAL_PWM_DIR_GPIO_Port,
              GPIO_MODE_AIN,    // 模拟输入模式（最低功耗）
              GPIO_OSPEED_2MHZ, // 低速配置
              SIGNAL_PWM_DIR_Pin);

    // 重置ENA引脚配置
    gpio_init(SIGNAL_PWM_ENA_GPIO_Port,
              GPIO_MODE_AIN,
              GPIO_OSPEED_2MHZ,
              SIGNAL_PWM_ENA_Pin);
}

/***
 * @brief  GPIO初始化(HOME)
 * @param  NULL
 */
void REIN_GPIO_HOME_Init(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_AF);
    gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
    nvic_irq_enable(EXTI10_15_IRQn, 0, 0);
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_15);
    exti_init(EXTI_15, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
    exti_interrupt_flag_clear(EXTI_15); // 清中断标志
}
